import random

class Position:
    def __init__(self,value=0,maxN=-1):
        self.value=value

        while self.value<0: self.value+=maxN
        while self.value>maxN:self.value-=maxN

        self.__maxN=maxN

    def __add__(self,other):
        if isinstance(other,Position):
            res=self.value+other.value
        elif isinstance(other,int):
            res=self.value+other
        else:
            raise TypeError

        if res>self.__maxN: 
            res=res-self.__maxN

        return Position(res,self.__maxN)

    def __neg__(self):
        return Position(self.__maxN-self.value,self.__maxN)

    def __pos__(self):
        return Position(self.value,self.__maxN)

    def __sub__(self,other):
        return self+(-other)

    def __radd__(self,other):
        return self+other

    def __rsub__(self,other):
        return -self+other

    def __cmp__(self,other):
        if isinstance(other,int):
            return cmp(self.value,other)

        return cmp(self.value,other.value)

    def __hash__(self):
        return int.__hash__(self.value)

    def __str__(self):
        return str(self.value)

    def inRange(self,x,r,withEdge=False):
        if r<0: r=-r

        if withEdge:
            return self<=x<=self+r
        else:
            return self<x<self+r

from collections import defaultdict

class Player:
    def __init__(self,manager,name,code,initPos=0,initSaving=0,initCash=0,points=0,estates=None,inv=None):
        object.__init__(self)

        self.manager=manager
        self.__maxN=self.manager.game.maxN
        self.code=code
        self.dir_=1

        self.name=name
        self.pos=initPos
        self.cash=initCash
        self.saving=initSaving
        self.points=points

        self.estates=estates or []
        self.inv=inv or defaultdict(lambda : 0)

        self.toss=self.basicToss
        self.stop=self.basicStop

    def __setattr__(self,name,value):
        if name=='pos':
            if not isinstance(value,(Position,int)):
                raise TypeError
            elif isinstance(value,int):
                value=Position(value,self.__maxN)

        self.__dict__[name]=value


    def __eq__(self,other):
        if not isinstance(other,Player):
            return False

        return self.code==other.code

    def __ne__(self,other):
        return not self==other

    def __cmp__(self,other):
        if not isinstance(other,Player):
            raise TypeError

        return cmp(self.estateAll(),other.estateAll()) \
            or cmp(self.saving+self.cash,other.saving+other.cash) or cmp(id(self),id(other))

    def estateAll(self):
        return sum( (e.value() for e in self.estates) )
        return 0

    def inAll(self):
        return self.esateAll()+self.cash+self.saving

    def __format__(self,*args,**kwargs):
        return self.name

    def __str__(self):
        return self.name

    def basicToss(self):
        return random.randint(1,6)

    def invChoice(self):
        choiceList=[]

        for code,number in self.inv.iteritems():
            if not number:
                continue
            
            card=self.manager.game.cardList[code]
            choiceList.append( ("{} x{}".format(card.__name__,number),code) )
            choiceList.sort(cmp=lambda x,y:cmp(x[1],y[1]))

        choice=self.manager.game.choice(
                choiceList,
                prompt="Inv list:",
                errorMsg="Input not valid",
                )

        return choice

    def basicStop(self,location):
        location.run(self)

    def profile(self):
        return self.name,self.cash,self.saving,self.points,self.estateAll()
